package com.example.show_auto.data

import android.content.Context
import android.content.SharedPreferences
import com.example.show_auto.network.ApiService
import com.example.show_auto.network.PersonalDataResponse
import com.example.show_auto.network.PersonalRecipeData
import com.example.show_auto.network.PersonalChefData
import com.example.show_auto.network.PersonalRecipeData as NetworkPersonalRecipeData
import com.example.show_auto.network.PersonalChefData as NetworkPersonalChefData
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.json.JSONObject

/**
 * 个人数据管理器
 * 负责从API获取个人数据并应用到游戏数据中
 */
class PersonalDataManager(private val context: Context) {
    
    private val apiService = ApiService()
    private val gson = Gson()
    private val sharedPrefs: SharedPreferences = 
        context.getSharedPreferences("personal_data", Context.MODE_PRIVATE)
    
    /**
     * 通过校验码获取并应用个人数据
     * 对应web项目中的个人数据导入功能
     */
    suspend fun importPersonalData(token: String, gameData: GameData): Result<GameData> = withContext(Dispatchers.IO) {
        try {
            // 1. 从API获取个人数据
            val apiResult = apiService.getPersonalData(token)
            if (apiResult.isFailure) {
                val error = apiResult.exceptionOrNull()!!
                return@withContext Result.failure(error)
            }

            val responseBody = apiResult.getOrNull()!!

            // 2. 解析个人数据
            val personalData = try {
                parsePersonalDataResponse(responseBody)
            } catch (e: Exception) {
                return@withContext Result.failure(Exception("数据解析失败: ${e.message}"))
            }

            // 3. 应用个人数据到游戏数据
            val updatedGameData = try {
                applyPersonalData(gameData, personalData)
            } catch (e: Exception) {
                return@withContext Result.failure(Exception("数据应用失败: ${e.message}"))
            }

            // 4. 保存个人数据到本地
            try {
                savePersonalDataToLocal(token, responseBody)
            } catch (e: Exception) {
                // 保存失败不影响主要功能，忽略错误
            }

            Result.success(updatedGameData)
        } catch (e: Exception) {
            Result.failure(Exception("导入个人数据失败: ${e.message}"))
        }
    }
    
    /**
     * 解析API返回的个人数据
     */
    private fun parsePersonalDataResponse(responseBody: String): PersonalDataResponse {
        try {
            val json = JSONObject(responseBody)

            // 解析菜谱数据 - 支持新的数据格式
            val recipesMap = mutableMapOf<String, PersonalRecipeData>()

            // 检查是否是新格式 (msg.recipes数组)
            if (json.has("msg") && json.getJSONObject("msg").has("recipes")) {
                val msgJson = json.getJSONObject("msg")
                val recipesArray = msgJson.getJSONArray("recipes")

                for (i in 0 until recipesArray.length()) {
                    try {
                        val recipeJson = recipesArray.getJSONObject(i)
                        // 兼容处理：API返回的ID可能是数字或字符串
                        val id = if (recipeJson.has("id")) {
                            when (val idValue = recipeJson.get("id")) {
                                is Number -> idValue.toString()
                                is String -> idValue
                                else -> ""
                            }
                        } else ""
                        val gotValue = recipeJson.optString("got", "")
                        val rankValue = recipeJson.optString("rank", "")

                        if (id.isNotEmpty()) {
                            val isGot = gotValue == "是"
                            val numericRank = convertRankToNumber(rankValue)

                            recipesMap[id] = PersonalRecipeData(
                                got = isGot,
                                rank = numericRank
                            )
                            
                        }
                    } catch (e: Exception) {
                        // 跳过解析失败的菜谱
                    }
                }
            }
            // 兼容旧格式 (recipes对象)
            else if (json.has("recipes")) {
                try {
                    val recipesJson = json.getJSONObject("recipes")
                    val keys = recipesJson.keys()
                    while (keys.hasNext()) {
                        val key = keys.next()
                        try {
                            val recipeJson = recipesJson.getJSONObject(key)
                            val gotValue = recipeJson.optString("got", "")
                            val rankValue = recipeJson.optInt("rank", 0)
                            val isGot = gotValue == "是"

                            recipesMap[key] = PersonalRecipeData(
                                got = isGot,
                                rank = rankValue
                            )

                        } catch (e: Exception) {
                            // 单个菜谱解析失败，跳过继续处理其他菜谱
                        }
                    }
                } catch (e: Exception) {
                    // 解析菜谱数据失败，忽略
                }
            }
            
            // 解析厨师数据
            val chefsMap = mutableMapOf<String, PersonalChefData>()

            // 检查是否是新格式 (msg.chefs数组)
            if (json.has("msg") && json.getJSONObject("msg").has("chefs")) {
                val msgJson = json.getJSONObject("msg")
                val chefsArray = msgJson.getJSONArray("chefs")

                for (i in 0 until chefsArray.length()) {
                    try {
                        val chefJson = chefsArray.getJSONObject(i)
                        // 兼容处理：API返回的ID可能是数字或字符串
                        val id = if (chefJson.has("id")) {
                            when (val idValue = chefJson.get("id")) {
                                is Number -> idValue.toString()
                                is String -> idValue
                                else -> ""
                            }
                        } else ""
                        val gotValue = chefJson.optString("got", "")
                        val ultValue = chefJson.optString("ult", "")
                        val equipValue = if (chefJson.has("equip")) chefJson.optInt("equip") else null
                        val dlvValue = if (chefJson.has("dlv")) chefJson.optInt("dlv") else null
                        val ambersList = if (chefJson.has("ambers")) {
                            val arr = chefJson.getJSONArray("ambers")
                            (0 until arr.length()).map { arr.optInt(it) }
                        } else null

                        if (id.isNotEmpty()) {
                            val isGot = gotValue == "是"
                            val isUlt = ultValue == "是"

                            chefsMap[id] = PersonalChefData(
                                got = isGot,
                                rank = 0, // 厨师数据中没有rank字段
                                ult = isUlt,
                                equip = equipValue,
                                dlv = dlvValue,
                                ambers = ambersList
                            )
                            
                        }
                    } catch (e: Exception) {
                        // 跳过解析失败的厨师
                    }
                }
            }
            // 兼容旧格式 (chefs对象)
            else if (json.has("chefs")) {
                try {
                    val chefsJson = json.getJSONObject("chefs")
                    val keys = chefsJson.keys()
                    while (keys.hasNext()) {
                        val key = keys.next()
                        try {
                            val chefJson = chefsJson.getJSONObject(key)
                            val gotValue = chefJson.optString("got", "")
                            val ultValue = chefJson.optString("ult", "")
                            val equipValue = if (chefJson.has("equip")) chefJson.optInt("equip") else null
                            val dlvValue = if (chefJson.has("dlv")) chefJson.optInt("dlv") else null
                            val ambersList = if (chefJson.has("ambers")) {
                                val arr = chefJson.getJSONArray("ambers")
                                (0 until arr.length()).map { arr.optInt(it) }
                            } else null
                            chefsMap[key] = PersonalChefData(
                                got = gotValue == "是",
                                rank = chefJson.optInt("rank", 0),
                                ult = ultValue == "是",
                                equip = equipValue,
                                dlv = dlvValue,
                                ambers = ambersList
                            )
                        } catch (e: Exception) {
                            // 单个厨师解析失败，跳过继续处理其他厨师
                        }
                    }
                } catch (e: Exception) {
                    // 解析厨师数据失败，忽略
                }
            }
            
            return PersonalDataResponse(
                recipes = recipesMap,
                chefs = chefsMap,
                timestamp = json.optLong("timestamp", System.currentTimeMillis()),
                version = json.optString("version", "1.0")
            )
        } catch (e: Exception) {
            throw Exception("解析个人数据失败: ${e.message}")
        }
    }
    
    /**
     * 将个人数据应用到游戏数据中
     */
    private fun applyPersonalData(gameData: GameData, personalData: PersonalDataResponse): GameData {
        // 更新菜谱数据
        var recipeUpdatedCount = 0
        var recipeGotCount = 0

        val updatedRecipes = gameData.recipes.map { recipe ->
            val personalRecipe = personalData.recipes?.get(recipe.recipeId)
            if (personalRecipe != null) {
                recipeUpdatedCount++
                if (personalRecipe.got && !recipe.got) {
                    recipeGotCount++
                }
                recipe.copy(
                    got = personalRecipe.got,
                    rank = personalRecipe.rank
                )
            } else {
                recipe
            }
        }
        
        // 更新厨师数据
        var chefUpdatedCount = 0
        var ultUpdatedCount = 0
        var totalUltimateChefs = 0
        val updatedChefs = gameData.chefs.map { chef ->
            val personalChef = personalData.chefs?.get(chef.chefId)
            if (personalChef != null) {
                chefUpdatedCount++
                if (personalChef.ult != chef.ult) {
                    ultUpdatedCount++
                    if (personalChef.ult) {
                        totalUltimateChefs++
                    }
                }
                chef.copy(
                    got = personalChef.got,
                    rank = personalChef.rank,
                    ult = personalChef.ult
                )
            } else {
                chef
            }
        }
        
        val finalData = gameData.copy(
            recipes = updatedRecipes,
            chefs = updatedChefs
        )

        // 验证应用结果
        val finalGotCount = finalData.recipes.count { it.got }
        val finalGotChefs = finalData.chefs.count { it.got }
        return finalData
    }
    
    /**
     * 保存个人数据到本地
     */
    private fun savePersonalDataToLocal(token: String, responseBody: String) {
        sharedPrefs.edit()
            .putString("last_token", token)
            .putString("personal_data", responseBody)
            .putLong("last_update", System.currentTimeMillis())
            .apply()
    }
    
    /**
     * 从本地加载个人数据
     */
    fun loadPersonalDataFromLocal(): String? {
        return sharedPrefs.getString("personal_data", null)
    }
    
    /**
     * 获取上次使用的校验码
     */
    fun getLastToken(): String? {
        return sharedPrefs.getString("last_token", null)
    }
    
    /**
     * 检查是否有本地保存的个人数据
     */
    fun hasLocalPersonalData(): Boolean {
        return sharedPrefs.contains("personal_data")
    }

    /**
     * 获取保存的个人数据JSON字符串
     */
    fun getPersonalDataJson(): String {
        return sharedPrefs.getString("personal_data", "") ?: ""
    }

    /**
     * 从JSON字符串解析PersonalData对象
     */
    fun parsePersonalData(personalDataJson: String): PersonalData? {
        return try {
            val personalDataResponse = parsePersonalDataResponse(personalDataJson)
            convertResponseToPersonalData(personalDataResponse)
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 将PersonalDataResponse转换为PersonalData
     */
    private fun convertResponseToPersonalData(response: PersonalDataResponse): PersonalData {
        val recipes = response.recipes?.mapValues { (_, data) ->
            com.example.show_auto.data.PersonalRecipe(
                got = data.got,
                rank = data.rank
            )
        } ?: emptyMap()

        val chefs = response.chefs?.mapValues { (_, data) ->
            com.example.show_auto.data.PersonalChef(
                got = data.got,
                rank = data.rank,
                ult = data.ult,
                equip = data.equip,
                dlv = data.dlv,
                ambers = data.ambers
            )
        } ?: emptyMap()

        return PersonalData(
            recipes = recipes,
            chefs = chefs
        )
    }

    /**
     * 直接从JSON字符串导入个人数据（用于从持久化存储恢复）
     */
    suspend fun importPersonalData(personalDataJson: String): Result<GameData> = withContext(Dispatchers.IO) {
        try {
            // 获取当前游戏数据
            val gameDataManager = GameDataManager(context)
            val gameDataResult = gameDataManager.loadGameData()
            if (gameDataResult.isFailure) {
                return@withContext Result.failure(Exception("游戏数据加载失败: ${gameDataResult.exceptionOrNull()?.message}"))
            }
            val gameData = gameDataResult.getOrNull()!!

            // 解析个人数据
            val personalData = try {
                parsePersonalDataResponse(personalDataJson)
            } catch (e: Exception) {
                return@withContext Result.failure(Exception("数据解析失败: ${e.message}"))
            }

            // 应用个人数据到游戏数据
            val updatedGameData = try {
                applyPersonalData(gameData, personalData)
            } catch (e: Exception) {
                return@withContext Result.failure(Exception("数据应用失败: ${e.message}"))
            }

            Result.success(updatedGameData)
        } catch (e: Exception) {
            Result.failure(Exception("导入个人数据失败: ${e.message}"))
        }
    }
    
    /**
     * 获取数据最后更新时间
     */
    fun getLastUpdateTime(): Long {
        return sharedPrefs.getLong("last_update", 0)
    }
    
    /**
     * 获取当前用户token
     */
    fun getCurrentUserToken(): String? {
        return sharedPrefs.getString("last_token", null)
    }
    
    /**
     * 保存当前用户的光环厨师配置
     */
    fun saveUserAuraChefs(auraChefNames: Set<String>) {
        val token = getCurrentUserToken()
        if (token != null) {
            val key = "aura_chefs_$token"
            val json = gson.toJson(auraChefNames)
            sharedPrefs.edit()
                .putString(key, json)
                .apply()
        }
    }
    
    /**
     * 获取当前用户的光环厨师配置
     */
    fun getUserAuraChefs(): Set<String> {
        val token = getCurrentUserToken()
        return if (token != null) {
            val key = "aura_chefs_$token"
            val json = sharedPrefs.getString(key, null)
            if (json != null) {
                try {
                    val type = object : TypeToken<Set<String>>() {}.type
                    gson.fromJson(json, type) ?: emptySet()
                } catch (e: Exception) {
                    emptySet()
                }
            } else {
                emptySet()
            }
        } else {
            emptySet()
        }
    }
    
    /**
     * 检查当前用户是否已设置过光环厨师
     */
    fun hasUserAuraChefsBeenSet(): Boolean {
        val token = getCurrentUserToken()
        return if (token != null) {
            val key = "aura_chefs_$token"
            sharedPrefs.contains(key)
        } else {
            false
        }
    }
    
    /**
     * 清除本地个人数据
     */
    fun clearLocalPersonalData() {
        sharedPrefs.edit().clear().apply()
    }
    
    /**
     * 使用本地保存的个人数据
     */
    suspend fun useLocalPersonalData(gameData: GameData): Result<GameData> = withContext(Dispatchers.IO) {
        try {
            val localData = loadPersonalDataFromLocal()
            if (localData == null) {
                return@withContext Result.failure(Exception("没有本地保存的个人数据"))
            }

            val personalData = parsePersonalDataResponse(localData)
            val updatedGameData = applyPersonalData(gameData, personalData)

            Result.success(updatedGameData)
        } catch (e: Exception) {
            Result.failure(Exception("使用本地数据失败: ${e.message}"))
        }
    }

    /**
     * 将字符串品阶转换为数字
     */
    private fun convertRankToNumber(rankStr: String): Int {
        return when (rankStr) {
            "" -> 0      // 未制作
            "普" -> 1    // 普通
            "优" -> 2    // 优级
            "特" -> 3    // 特级
            "神" -> 4    // 神级
            "传" -> 5    // 传说级（如果有的话）
            else -> 0
        }
    }
}


